package com.frank.loadinglibrary.common.other;

import com.frank.loadinglibrary.common.BaseLoadingComponent;
import com.frank.loadinglibrary.utils.Indicator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.ArrayList;

public class ChromeFloatingCirclesComponent extends BaseLoadingComponent implements Component.DrawTask {

    Color[] colors = new Color[]{new Color(Color.getIntColor("#C93437")),
            new Color(Color.getIntColor("#375BF1")),
            new Color(Color.getIntColor("#F7D23E")),
            new Color(Color.getIntColor("#34A350"))};

    private int DEFALUT_DURTION = 3000;

    private Paint mLeft_Top_Paint;
    private Paint mRight_Top_Paint;
    private Paint mLeft_Buttom_Paint;
    private Paint mRight_Buttom_Paint;

    //绘制圆球的半径
    float mCircleRadius = 30;
    float mRectSpace = 120;
    float mOffset = 0;
    private Indicator<AnimatorValue> indicator;


    public ChromeFloatingCirclesComponent(Context context) {
        this(context, null);
    }

    public ChromeFloatingCirclesComponent(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public ChromeFloatingCirclesComponent(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init();
    }

    public ChromeFloatingCirclesComponent(Context context, AttrSet attrSet, int resId) {
        super(context, attrSet, resId);
        init();
    }

    private void init() {
        setPaint();
        setDurtion(DEFALUT_DURTION);
        indicator = new Indicator<AnimatorValue>() {
            @Override
            public ArrayList<AnimatorValue> onCreateAnimators() {
                ArrayList<AnimatorValue> animators = new ArrayList<AnimatorValue>();
                AnimatorValue animatorValue = new AnimatorValue();
                animatorValue.setDuration(durtion);
                animatorValue.setLoopedCount(-1);
                animators.add(animatorValue);
                this.addUpdateListener(animatorValue, (animatorValue1, v) -> {
                    mOffset = v;
                    ChromeFloatingCirclesComponent.this.invalidate();
                });
                return animators;
            }
        };
        setBindStateChangedListener(new BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {
                if (autoStart) {
                    startAnimators();
                }
            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {
                stopAnimators();
            }
        });
        addDrawTask(this);
    }

    @Override
    protected void stopAnimators() {
        if (indicator != null && indicator.isRunning()) {
            indicator.stop();
        }
    }

    @Override
    protected void startAnimators() {
        if (indicator != null && !indicator.isRunning()) {
            indicator.start();
        }
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        float width = getWidth();
        float height = getHeight();
        drawLeftTopCircle(width, height, canvas);
        drawLeftButtomCircle(width, height, canvas);
        drawRightButtomCircle(width, height, canvas);
        drawRightTopCircle(width, height, canvas);
    }

    private void drawLeftTopCircle(float width, float height, Canvas canvas) {
        float mLeft_Top_CenterX;
        float mLeft_Top_CenterY;
        if (mOffset <= 0.5) {
            mLeft_Top_CenterX = (float) (width / 2 - mRectSpace / 2 + mOffset * mRectSpace * 2);
            mLeft_Top_CenterY = height / 2 - mRectSpace / 2 + mOffset * mRectSpace * 2;
        } else {
            mLeft_Top_CenterX = (float) (width / 2 - mRectSpace / 2 + (1 - mOffset) * mRectSpace * 2);
            mLeft_Top_CenterY = (float) (height / 2 - mRectSpace / 2 + (1 - mOffset) * mRectSpace * 2);
        }
        canvas.drawCircle(mLeft_Top_CenterX, mLeft_Top_CenterY, mCircleRadius, mLeft_Top_Paint);
    }

    private void drawLeftButtomCircle(float width, float height, Canvas canvas) {
        float mLeft_Buttom_CenterX;
        float mLeft_Buttom_CenterY;
        if (mOffset <= 0.5) {
            mLeft_Buttom_CenterX = width / 2 - mRectSpace / 2 + mOffset * mRectSpace * 2;
            mLeft_Buttom_CenterY = height / 2 + mRectSpace / 2 - mOffset * mRectSpace * 2;
        } else {
            mLeft_Buttom_CenterX = (float) (width / 2 - mRectSpace / 2 + (1 - mOffset) * mRectSpace * 2);
            mLeft_Buttom_CenterY = (float) (height / 2 + mRectSpace / 2 - (1 - mOffset) * mRectSpace * 2);
        }
        canvas.drawCircle(mLeft_Buttom_CenterX, mLeft_Buttom_CenterY, mCircleRadius, mLeft_Buttom_Paint);
    }

    private void drawRightTopCircle(float width, float height, Canvas canvas) {
        float mRight_Top_CenterX;
        float mRight_Top_CenterY;
        if (mOffset <= 0.5) {
            mRight_Top_CenterX = width / 2 + mRectSpace / 2 - mOffset * mRectSpace * 2;
            mRight_Top_CenterY = height / 2 - mRectSpace / 2 + mOffset * mRectSpace * 2;
        } else {
            mRight_Top_CenterX = (float) (width / 2 + mRectSpace / 2 - (1 - mOffset) * mRectSpace * 2);
            mRight_Top_CenterY = (float) (height / 2 - mRectSpace / 2 + (1 - mOffset) * mRectSpace * 2);
        }
        canvas.drawCircle(mRight_Top_CenterX, mRight_Top_CenterY, mCircleRadius, mRight_Top_Paint);
    }

    private void drawRightButtomCircle(float width, float height, Canvas canvas) {
        float mRight_Buttom_CenterX;
        float mRight_Buttom_CenterY;
        if (mOffset <= 0.5) {
            mRight_Buttom_CenterX = width / 2 + mRectSpace / 2 - mOffset * mRectSpace * 2;
            mRight_Buttom_CenterY = height / 2 + mRectSpace / 2 - mOffset * mRectSpace * 2;
        } else {
            mRight_Buttom_CenterX = (float) (width / 2 + mRectSpace / 2 - (1 - mOffset) * mRectSpace * 2);
            mRight_Buttom_CenterY = (float) (height / 2 + mRectSpace / 2 - (1 - mOffset) * mRectSpace * 2);
        }
        canvas.drawCircle(mRight_Buttom_CenterX, mRight_Buttom_CenterY, mCircleRadius, mRight_Buttom_Paint);
    }


    private void setPaint() {
        Paint basePaint = new Paint();
        basePaint.setAntiAlias(true);
        basePaint.setStyle(Paint.Style.FILL_STYLE);
        basePaint.setStrokeWidth(2);

        mLeft_Top_Paint = new Paint(basePaint);
        mLeft_Top_Paint.setColor(colors[0]);

        mRight_Top_Paint = new Paint(basePaint);
        mRight_Top_Paint.setColor(colors[1]);

        mLeft_Buttom_Paint = new Paint(basePaint);
        mLeft_Buttom_Paint.setColor(colors[2]);

        mRight_Buttom_Paint = new Paint(basePaint);
        mRight_Buttom_Paint.setColor(colors[3]);
    }

    public ChromeFloatingCirclesComponent setColor(Color[] color) throws Exception {
        if (color.length != 4) {
            throw new Exception("setColor的长度和球的个数不一致");
        }
        this.colors = color;
        setPaint();
        return this;
    }

    /**
     * 设置小球半径
     */
    public ChromeFloatingCirclesComponent setCircleRaius(float raius) {
        this.mCircleRadius = raius;
        return this;
    }

    /**
     * 两个小球之间的间距
     *
     * @param mRectSpace
     * @return
     */
    public ChromeFloatingCirclesComponent setRectSpace(float mRectSpace) {
        this.mRectSpace = mRectSpace;
        return this;
    }
}
